package com.thh.shirodemo.config;

import com.thh.shirodemo.bean.User;
import com.thh.shirodemo.mapper.UserMapper;
import com.thh.shirodemo.service.UserService;
import org.apache.shiro.authc.*;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.util.ByteSource;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.annotation.Configuration;

import javax.annotation.Resource;
import java.util.List;

/**
 * @author shkstart
 * @create 2022-07-18-0:02
 */
@Configuration //注入realm
public class MyRealm extends AuthorizingRealm {
    @Resource
    UserService userService;

    @Resource
    UserMapper userMapper;
    private Logger logger=LoggerFactory.getLogger(MyRealm.class);

    //授权
    //controller中调用时
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
        logger.info("shiro的授权方法");
        SimpleAuthorizationInfo authorizationInfo=new SimpleAuthorizationInfo();
        //获取当前资源 就是下面new SimpleAuthenticationInfo(user,user.getUserPass(),"myRealm");中的user
        User user = (User) principalCollection.asList().get(0);

        //需要绑定角色和资源
        authorizationInfo.addRole(String.valueOf(user.getUserRoles()));
        authorizationInfo.addStringPermissions(user.getUserPerms());

        return  authorizationInfo;
    }

    //认证
    //登录时
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
        logger.info("shiro的认证方法");
        //获取当前用户
        UsernamePasswordToken userToken=(UsernamePasswordToken) token;
        String username=userToken.getUsername();

        //获得数据库中的用户来和当前用户进行比对，认证
        User user = userService.queryUserByName(username);
        //如果没有查到用户 表示没有该用户
        if(user==null){
            return null;
            //后面会抛出UnknownAccountException异常
        }
        List<String> roles = userMapper.getRoles(user.getUserRoles());
        user.setUserPerms(roles);

        //加入我们需要的添加的盐用来加密
        ByteSource salt = ByteSource.Util.bytes("saltAdrian");
        //返回AuthenticationToken,完成认证流程

        SimpleAuthenticationInfo simpleAuthenticationInfo = new SimpleAuthenticationInfo(user,user.getUserPass(),salt,"myRealm");
        //shiro帮我们进行密码认证(密码敏感 已经包装好了)
        return simpleAuthenticationInfo;
    }

}
